
import java.util.Date;
import java.util.logging.Logger;
import src.de.checker.hochzeit.domain.util.*;
import src.de.checker.hochzeit.domain.user.*;
import src.de.checker.hochzeit.domain.budget.*;
import src.de.checker.hochzeit.konstanten.Konstanten;
import src.de.checker.hochzeit.util.*;
import com.google.appengine.api.datastore.*
import static com.google.appengine.api.datastore.FetchOptions.Builder.*
/**
 * Verwaltet die Funktionen, die für die Budgetliste nötig sind.
 */
Logger log = Logger.getLogger('BudgetController');

def myuser = session.getAttribute(Konstanten.SESSION_USER);

if(myuser != null)
{
	if(params?.index ==~ /(?i)true/)
	{
		index()
	}
	if(params?.createdefault ==~ /(?i)true/)
	{
		createFromDefault()
	}
	if(params?.create ==~ /(?i)true/)
	{
		create()
	}
	if(params?.save ==~ /(?i)true/)
	{
		save()
	}
	if(params?.delete ==~ /(?i)true/)
	{
		delete()
	}
	if(params?.edit ==~ /(?i)true/)
	{
		edit()
	}
	if(params?.update ==~ /(?i)true/)
	{
		update()
	}
}
private void index()
{
	def myuser = session.getAttribute(Konstanten.SESSION_USER);

	//Kategorien suchen
	def query1 = new Query(Konstanten.BKATEGORIE)
	query1.addSort("id", Query.SortDirection.ASCENDING)
	PreparedQuery preparedQuery1 = datastore.prepare(query1)
 	def kategorien = preparedQuery1.asList( withLimit(300) )
 	//Budgetplan für die Feier des angemeldeten Benutzers suchen
 	def query = new Query(Konstanten.BUDGET)
	query.addFilter("feier", Query.FilterOperator.EQUAL, myuser.feier)
	query.addSort("kurzbeschreibung", Query.SortDirection.ASCENDING)
	PreparedQuery preparedQuery = datastore.prepare(query)
 	def checkliste = preparedQuery.asList( withLimit(300) )
	HashMap liste = new HashMap();
 	
	Long firstkat = -1
 	boolean firstkatIsSet = false
	
 	double summe = 0;
	double kalk = 0;
 	
	for(kat in kategorien)
 	{
 		String b = kat.beschreibung
 		Long id = kat.id
 		List katcheck = new ArrayList()
 		for(check in checkliste)
 		{
 			if(kat.key == check.kategorie)
 			{
 				if(check.kosten)
 					summe += check.kosten
 				if(check.kalkulierteKosten)
 					kalk += check.kalkulierteKosten
 				katcheck.add(check)
 				if(!firstkatIsSet)
 				{
 					firstkat = id
 					firstkatIsSet = true
 				}
 			}
 		}
 		liste.put id, katcheck
 	}
	request['summe'] = summe
	request['kalk'] = kalk
	request['list'] = checkliste
	request['firstkat'] = firstkat
 	request['kat'] = kategorien
 	request['checkmap'] = liste
 	
 	forward '/budget/uebersicht.gtpl'
}
/**
 * Löscht die Budgetlisteneinträge für den angemeldeten Benutzer
 * @param feier
 */
private void deleteBudgetForFeier(String feier)
{
	def user = session.getAttribute(Konstanten.SESSION_USER)
	def query = new Query(Konstanten.BUDGET)
	query.addFilter("feier", Query.FilterOperator.EQUAL, feier)
	PreparedQuery preparedQuery = datastore.prepare(query)
	def entities = preparedQuery.asList( withLimit(1000) )
	int counter = 0
	for(i in entities)
	{
		counter++
		i.delete()
	}
	if(counter > 0)
	{
		log.info('Benutzer: '+user+' die alten Einträge der Budgetliste gelöscht (Anzahl:'+counter+')')
		String message =  'Alle Einträge aus der Budgetliste für die Feier '+feier+' gelöscht.'
		createTracer(Konstanten.TRACER_DELETE, message)
	}
}
/**
 * Erstellt eine Checkliste für die Feier des angemeldeten Benutzers
 * aus den Einträgen der Default-Checkliste
 */
private void createFromDefault()
{
	def user = session.getAttribute(Konstanten.SESSION_USER)
	String feier = user.feier
	//Eigentlich unnötig, weil diese Funktion laut Auth-Filter nur den Rollen 0 zugeordnet ist
	if(user.rolle == 0)
	{
		deleteBudgetForFeier(feier)
		
		def query = new Query(Konstanten.DEFAULT_BUDGET)
		PreparedQuery preparedQuery = datastore.prepare(query)
	 	def entities = preparedQuery.asList( withLimit(300) )
	 	int counter = 0
	 	Key myuser = user.key
	 	for(i in entities)
	 	{
	 		counter++
	 		Budget item = new Budget();
	 		item.kurzbeschreibung = i.kurzbeschreibung
	 		item.anmerkung = i.anmerkung
	 		item.kategorie = i.kategorie
	 		item.kalkulierteKosten = i.kalkulierteKosten
	 		item.feier = feier
	 		
	 		Entity e2 = item as Entity
	 		e2.save()
	 	}
		if(counter > 0)
		{
			log.info('Benutzer: '+user+' hat einen neuen Budgetplan aus dem Defaultset erstellt')
			log.info('Items (Anzahl:'+counter+') aus dem Default Budgetplan für Feier '+feier+' übernommen.')
			String message = 'Neuer Budgetplan aus Default Budgetplan für Feier '+feier+'(Anzahl:'+counter+')'
		    createTracer(Konstanten.TRACER_CREATE, message)
		}
	}
	else
	{
		String message = 'Versuch einen neuen Budgetplan aus dem Defaultbudgetplan zu erstellen. '
		log.warning("Der Benutzer "+user+"hat versucht einen Budgetplan aus dem Defaultbudgetplan zu erstellen, obwohl er " +
				"nicht zum Brautpaar gehört! Abgebrochen!")
		createTracer(Konstanten.TRACER_VERBOTEN, message)
	}	
	index()
}
private void save()
{
	if(!params.kurzbeschreibung)
	{
		request.message = 'Es muss mindestens Kurzbeschreibung angegeben werden.'
		create()
	}
	else
	{
		Entity entity = new Entity(Konstanten.BUDGET)
		entity['kurzbeschreibung'] = params.kurzbeschreibung
		entity['anmerkung'] = params.anmerkung
		entity['feier'] = session.getAttribute(Konstanten.SESSION_USER).feier
		entity['kategorie'] = KeyFactory.stringToKey(params.kategorie)
		try
		{
			String x = params.kosten
			x = x.replaceAll(',','.')
			Double kostenVA = new Double(x)
			entity['kosten'] = kostenVA
		}
		catch(Exception e){}
		try
		{
			String x = params.kalkulierteKosten
			x = x.replaceAll(',','.')
			Double kostenVA = new Double(x)
			entity['kalkulierteKosten'] = kostenVA
		}
		catch(Exception e){}
		entity.save()
		
		request.message = 'Budgetplan Eintrag gespeichert'
		log.info("Budgetplan Eintrag gespeichert: "+entity)
		index()
	}
}
/**
 * Löscht einen Budgetplan Eintrag
 */
private void delete()
{
	def myuser = session.getAttribute(Konstanten.SESSION_USER);
	try
	{
		Key k = KeyFactory.stringToKey(params.key)
		def checkitem = datastore.get(k);
		//Gehört der zu löschende Eintrag auch zum Benutzer?
		if(checkitem.feier.equals(myuser.feier) )
		{
			log.info ('Lösche Budgetplaneintrag: '+checkitem+' [Gelöscht von: '+myuser+"]")
			createTracer(Konstanten.TRACER_DELETE, 'Budgetplaneintrag '+checkitem.key+' '+checkitem.kurzbeschreibung+' gelöscht')
		    checkitem.delete()
		}
		else
		{
			String message = 'Der Benutzer hat versucht ein Budgetplaneintrag zu löschen, der nicht zur eigenen Feier gehört '+checkitem.key
		    log.warning("budget.delete(): Budgetplaneintrag gehört nicht zur eigenen Feier:"+checkitem+" Benutzer der gesucht hat: "+myuser)
		    createTracer(Konstanten.TRACER_VERBOTEN, message)
		}
	}
	catch(Exception e)
	{
		String message = 'Es wurde ein Budgetplaneintrag zu löschen, den es nicht gibt. params.key: '+params.key 
		log.warning(e.toString())
		log.warning("budget.delete(): Budgetplaneintrag nicht gefunden zum löschen. Benutzer der gesucht hat: "+myuser+" Params: "+params)
		createTracer(Konstanten.TRACER_VERBOTEN, message)
	}
	redirect '/budget'
}

private Key getKey(String id, String kind)
{
	long mid = new Long(id).longValue()
	Key k = KeyFactory.createKey(kind,mid)
	return k
}
private void update()
{
	def nutzer = session.getAttribute(Konstanten.SESSION_USER)
	try
	{
		Key k = KeyFactory.stringToKey(params.key)
		def checkitem = datastore.get(k);
		//Überprüfen, ob der Eintrag zur eigenen Feier gehört
		if(checkitem.feier.equals(nutzer.feier) )
		{
			if(!params.kurzbeschreibung)
			{
				request.message = 'Es muss eine Kurzbeschreibung angegeben werden.'
				edit()
			}
			else
			{
				checkitem['kurzbeschreibung'] = params.kurzbeschreibung
				checkitem['anmerkung'] = params.anmerkung
				checkitem['kategorie'] = KeyFactory.stringToKey(params.kategorie)
				try
				{
					String x = params.kosten
					x = x.replaceAll(',','.')
					Double kostenVA = new Double(x)
					checkitem['kosten'] = kostenVA
				}
				catch(Exception e){}
				try
				{
					String x = params.kalkulierteKosten
					x = x.replaceAll(',','.')
					Double kostenVA = new Double(x)
					checkitem['kalkulierteKosten'] = kostenVA
				}
				catch(Exception e){}
				checkitem.save()
				String message = 'Budgetplaneintrag aktualisiert: '+k
				createTracer(Konstanten.TRACER_UPDATE, message)
				request.message = 'Budgetplaneintrag '+checkitem.kurzbeschreibung+' überarbeitet.'	
				log.info("Budgetplan Eintrag akutalisiert: "+checkitem)
				try
				{
					def ac = datastore.get(checkitem['kategorie']).id
					params.active = ac
				}
				catch(Exception e){
					
				}
			}
		}
		else
		{
			String message = 'Der Benutzer hat versucht einen Budgetplaneintrag zu updaten, dass nicht zur eigenen Feier gehört '+checkitem.key
		    createTracer(Konstanten.TRACER_VERBOTEN, message)
		}
		
	}
	catch(Exception e)
	{
		String message = 'Es wurde ein Budgetplaneintrag zu updaten, den es nicht gibt. params.key: '+params.key 
		createTracer(Konstanten.TRACER_VERBOTEN, message)
		log.warning(e.toString())
		log.warning("budget.update(): Budgetplaneintrag nicht gefunden zum update. Benutzer der gesucht hat: "+nutzer)
	}
	index()
}

private void create()
{
	createandedit()
	forward '/budget/create.gtpl'
}

private void edit()
{
	def myuser = session.getAttribute(Konstanten.SESSION_USER);
	try
	{
		Key k = KeyFactory.stringToKey(params.key)
		def entity = datastore.get(k);
		if(entity.feier.equals(myuser.feier))
		{
			request['checkitem'] =  entity
			createandedit()
			forward '/budget/edit.gtpl'
		}
		else
		{
			String message = 'Der Benutzer will ein Budgetplaneintrag editieren, dass nicht zur eigenen Feier gehört: '+entity.key
			log.warning("budget.edit(): Item gehört nicht zur eigenen Feier: "+entity+" Benutzer der gesucht hat: "+myuser)
			createTracer(Konstanten.TRACER_VERBOTEN, message)
			index()
		}
	}
	catch(Exception e)
	{
		String message = 'Es wurde ein Budgetplaneintrag zu editieren, das es nicht gibt. params.key: '+params.key 
		log.warning(e.toString())
		log.warning("checkliste.edit(): Item nicht gefunden zum editieren. Benutzer der gesucht hat: "+myuser)
		createTracer(Konstanten.TRACER_VERBOTEN, message)
		index()
	}
}

private void createandedit()
{
	def kquery = new Query(Konstanten.BKATEGORIE)
	kquery.addSort("id", Query.SortDirection.ASCENDING)
	PreparedQuery kpreparedQuery = datastore.prepare(kquery)
	def entitiesk = kpreparedQuery.asList( withLimit(100) )
	request['listkat'] = entitiesk
	
}

private void createTracer(String message)
{
	createTracer(Konstanten.TRACER_FORGOT, message);
}
private void createTracer(String type, String message) {
	try
	{
		def myuser = session.getAttribute(Konstanten.SESSION_USER);

		Tracer t = new Tracer()
	    t.ipadresse = request.getRemoteAddr()
	    t.user = myuser.key
	    t.type = type
	    t.nachricht = message
	    t.datum = Datehelper.getNow()
	    Entity e2 = t as Entity
		e2.save()
	}
	catch(Exception e)
	{
		
	}
}